package com.bizmda.bizsip.sink;

import cn.hutool.json.JSONObject;
import com.bizmda.bizsip.common.BizException;
import com.bizmda.bizsip.common.BizUtils;
import com.bizmda.bizsip.converter.Converter;
import com.bizmda.bizsip.sink.connector.BeanSinkConnector;
import com.bizmda.bizsip.sink.connector.Connector;
import com.bizmda.bizsip.sink.connector.SinkBeanSinkConnector;
import com.bizmda.bizsip.sink.connector.sinkbean.JSONObjectSinkBeanInterface;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Scope;
import org.springframework.context.annotation.ScopedProxyMode;
import org.springframework.stereotype.Service;

/**
 * @author 史正烨
 */
@Slf4j
@Service
@Scope(value = "prototype", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class Sink {
    @Value("${bizsip.config-path:#{null}}")
    private String configPath;
//    @Value("${spring.cloud.nacos.discovery.server-addr}")
//    private String serverAddr;

    private String sinkId;

    //    @Autowired
//    private SinkConfigMapping sinkConfigMapping;
//
//    private AbstractConverter converter;
//    private AbstractSinkConnector sinkConnector;
    private Converter converter = null;
    private Connector connector = null;

    @Deprecated
    public void init(String sinkId) throws BizException {
        this.converter = Converter.getSinkConverter(sinkId);
        this.connector = Connector.getSinkConnector(sinkId);
    }

//    private void load() throws BizException {
//        AbstractSinkConfig sinkConfig = this.sinkConfigMapping.getSinkConfig(this.sinkId);
//        if (sinkConfig == null) {
//            throw new BizException(BizResultEnum.SINK_NOT_SET, "sinkId[" + this.sinkId + "]在sink.yml中没有配置");
//        }
//        Class<Object> clazz;
//        if (sinkConfig.getConverterMap() == null) {
//            this.converter = null;
//        }
//        else {
//            String converterType = (String) sinkConfig.getConverterMap().get("type");
//            clazz = (Class<Object>) AbstractConverter.CONVERTER_TYPE_MAP.get(converterType);
//            if (clazz == null) {
//                throw new BizException(BizResultEnum.CONVERTOR_NOT_SET);
//            }
//
//            try {
//                this.converter = (AbstractConverter) clazz.getDeclaredConstructor().newInstance();
//            } catch (InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e) {
//                throw new BizException(BizResultEnum.CONVERTOR_CREATE_ERROR, e);
//            }
//
//            this.converter.init(configPath, sinkConfig.getConverterMap());
//        }
//        if (sinkConfig.getConnectorMap() == null) {
//            this.sinkConnector = null;
//        }
//        else {
//            String connectorType = (String) sinkConfig.getConnectorMap().get("type");
//
//            clazz = (Class) AbstractSinkConnector.CONNECTOR_TYPE_MAP.get(connectorType);
//            if (clazz == null) {
//                throw new BizException(BizResultEnum.CONNECTOR_NOT_SET);
//            }
//
//            try {
//                this.sinkConnector = (AbstractSinkConnector) clazz.getDeclaredConstructor().newInstance();
//                this.sinkConnector.setType(connectorType);
//            } catch (InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e) {
//                throw new BizException(BizResultEnum.CONNECTOR_JAVA_CLASS_CREATE_ERROR, e);
//            }
//
//            this.sinkConnector.init(sinkConfig);
//        }
//    }

    @Deprecated
    public JSONObject process(JSONObject inMessage) throws BizException {
        log.trace("Sink传入消息:\n{}", BizUtils.buildJsonLog(inMessage));
        Object object;

        boolean isConverter = true;
        if ((this.connector.getSinkConnector() instanceof BeanSinkConnector)) {
            isConverter = false;
        } else if (this.connector.getSinkConnector() instanceof SinkBeanSinkConnector) {
            if (((SinkBeanSinkConnector) this.connector.getSinkConnector()).getSinkBean() instanceof JSONObjectSinkBeanInterface) {
                isConverter = false;
            }
        }

        if (!isConverter) {
            log.debug("Sink通过Connect[{}]调用服务", this.connector.getSinkConnector().getType());
            object = this.connector.getSinkConnector().process(inMessage);
            log.trace("Sink服务返回消息:\n{}", BizUtils.buildJsonLog((JSONObject) object));
            return (JSONObject) object;
        }
        log.debug("Sink调用Convert[{}]打包", this.converter.getConverter().getType());
        object = this.converter.pack(inMessage);
        log.trace("Sink打包后消息:\n{}", BizUtils.buildHexLog((byte[]) object));
        log.debug("Sink通过Connect[{}]调用服务", this.connector.getSinkConnector().getType());
        object = this.connector.getSinkConnector().process(object);
        JSONObject unpackedJsonObject;
        log.trace("Sink服务返回消息:\n{}", BizUtils.buildHexLog((byte[]) object));
        log.debug("Sink调用Convert[{}]解包", this.converter.getConverter().getType());
        unpackedJsonObject = this.converter.unpack((byte[]) object);
        log.trace("Sink返回消息:\n{}", BizUtils.buildJsonLog(unpackedJsonObject));
        return unpackedJsonObject;
    }

}
